using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Omniture.Studio.Objects;
using Omniture.API;
using System.Xml;
using System.IO;
using System.Collections.ObjectModel;
using WeifenLuo.WinFormsUI.Docking;
using System.Threading;
using System.Globalization;

namespace Omniture.Studio
{
	public partial class ProjectForm : DockContent
	{
		#region Class Members

		private OmnitureProject _project = null;
		private Options _options = null;
		private MDIForm _parentMDIForm = null;
		private PropertyGrid _propertyGrid = null;
		private bool _isLoading = false;
		private bool _isDirty = false;
		private ListViewHelper evarHelper = null;
		private ListViewHelper propHelper = null;
		private ListViewHelper eventHelper = null;

		#endregion

		#region Constructors

		public ProjectForm()
		{
			InitializeComponent();

			this.Activated += new EventHandler(ProjectForm_Activated);
			this.FormClosing += new FormClosingEventHandler(ProjectForm_FormClosing);
			this.FormClosed += new FormClosedEventHandler(ProjectForm_FormClosed);

			txtProjectName.TextChanged += new EventHandler(txtProjectName_TextChanged);
			txtConfigFileFolder.TextChanged += new EventHandler(txtConfigFileFolder_TextChanged);
			txtLibraryFolder.TextChanged += new EventHandler(txtLibraryFolder_TextChanged);
			txtScriptFile.TextChanged += new EventHandler(txtScriptFile_TextChanged);
			txtCompanyName.TextChanged += new EventHandler(txtCompanyName_TextChanged);
			txtGlobalScriptVar.TextChanged += new EventHandler(txtGlobalScriptVar_TextChanged);
			txtTrackDownloadLinks.TextChanged += new EventHandler(txtTrackDownloadLinks_TextChanged);
			txtTrackExternalLinks.TextChanged += new EventHandler(txtTrackExternalLinks_TextChanged);
			chkDebug.CheckedChanged += new EventHandler(chkDebug_CheckedChanged);
			lvwEvar.SelectedIndexChanged += new EventHandler(lvwEvar_SelectedIndexChanged);
			lvwEvent.SelectedIndexChanged += new EventHandler(lvwEvent_SelectedIndexChanged);
			lvwProp.SelectedIndexChanged += new EventHandler(lvwProp_SelectedIndexChanged);
			lstEvarReference.SelectedIndexChanged += new EventHandler(ReferenceListBox_SelectedIndexChanged);
			lstEventReference.SelectedIndexChanged += new EventHandler(ReferenceListBox_SelectedIndexChanged);
			lstPropReference.SelectedIndexChanged += new EventHandler(ReferenceListBox_SelectedIndexChanged);
			//tvwPage.AfterSelect += new TreeViewEventHandler(tvwPage_AfterSelect);
			lvwPage.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(lvwPage_ItemSelectionChanged);
			//tvwPage.MouseUp += new MouseEventHandler(tvwPage_MouseUp);
			txtCustomSubmit.TextChanged += new EventHandler(txtCustomSubmit_TextChanged);
			chkCustomSubmit.CheckedChanged += new EventHandler(chkCustomSubmit_CheckedChanged);

			lstEvarReference.DragEnter += new DragEventHandler(lstEvarReference_DragEnter);
			lstEvarReference.DragDrop += new DragEventHandler(lstEvarReference_DragDrop);
			lstPropReference.DragEnter += new DragEventHandler(lstPropReference_DragEnter);
			lstPropReference.DragDrop += new DragEventHandler(lstPropReference_DragDrop);
			lstEventReference.DragEnter += new DragEventHandler(lstEventReference_DragEnter);
			lstEventReference.DragDrop += new DragEventHandler(lstEventReference_DragDrop);
			lstEvarReference.KeyDown += new KeyEventHandler(lstEvarReference_KeyDown);
			lstPropReference.KeyDown += new KeyEventHandler(lstPropReference_KeyDown);
			lstEventReference.KeyDown += new KeyEventHandler(lstEventReference_KeyDown);
			//tvwPage.DragEnter += new DragEventHandler(tvwPage_DragEnter);
			//tvwPage.DragDrop += new DragEventHandler(tvwPage_DragDrop);
			//tvwPage.KeyDown += new KeyEventHandler(tvwPage_KeyDown);
			lvwPage.Parent.KeyDown += new KeyEventHandler(Parent_KeyDown);

			lvwPage.Columns.Add("Name", 150);
			lvwPage.Columns.Add("Path", 200);
			lvwPage.Columns.Add("Channel", 100);

			lvwEvar.Columns.Add("Name", 100);
			lvwEvar.Columns.Add("Alias", 100);
			lvwEvar.Columns.Add("Is Required", 100);
			lvwEvar.Columns.Add("Default Value", 100);
			evarHelper = new ListViewHelper(lvwEvar);

			lvwProp.Columns.Add("Name", 100);
			lvwProp.Columns.Add("Alias", 100);
			lvwProp.Columns.Add("Is Required", 100);
			lvwProp.Columns.Add("Default Value", 100);
			propHelper = new ListViewHelper(lvwProp);

			lvwEvent.Columns.Add("Name", 100);
			lvwEvent.Columns.Add("Alias", 100);
			eventHelper = new ListViewHelper(lvwEvent);

			this.wizard1.CancelText = "&Close";
			this.wizard1.FinishText = "&Build";
			this.wizard1.BeforeSwitchPages += new Gravitybox.Controls.Wizard.Wizard.BeforeSwitchPagesEventHandler(wizard1_BeforeSwitchPages);
			this.wizard1.AfterSwitchPages += new Gravitybox.Controls.Wizard.Wizard.AfterSwitchPagesEventHandler(wizard1_AfterSwitchPages);
			this.wizard1.Finish += new EventHandler(wizard1_Finish);
			this.DockStateChanged += new EventHandler(ProjectForm_DockStateChanged);
			this.IsDirty = false;

			this.AddTooTip(txtCompanyName, "Company Name", "Determines the name of your company. This is used in the name of the generated library.");
			this.AddTooTip(txtGlobalScriptVar, "Global Script Variable", "Determines the name script variable to use in javascript. This is usually 's'.");
			this.AddTooTip(txtConfigFileFolder, "Configuration Folder", "Determines the folder in which to generate the XML configuration file.");
			this.AddTooTip(txtLibraryFolder, "Library Folder", "Determines the folder in which to generate .NET web control library.");
			this.AddTooTip(txtProjectName, "Project Name", "Determines the name of this project.");
			this.AddTooTip(txtScriptFile, "S-Code File", "Determines the relative path the website of the Omniture 's_code' file.");
			this.AddTooTip(txtSummary, "Project Summary", "A summary of this project.");
			this.AddTooTip(cmdAddEvar, "Add Evar", "Add a global Evar object to this project");
			this.AddTooTip(cmdAddEvent, "Add Event", "Add a global Event object to this project");
			this.AddTooTip(cmdAddPage, "Add Site Page", "Add a page from your site for configuration");
			this.AddTooTip(cmdAddProp, "Add Prop", "Add a global Prop object to this project");
			this.AddTooTip(cmdDeleteEvar, "Delete Evar", "Delete the selected Evar object from this project. This will remove all references to this object.");
			this.AddTooTip(cmdDeleteEvent, "Delete Event", "Delete the selected Event object from this project. This will remove all references to this object.");
			this.AddTooTip(cmdDeletePage, "Delete Site Page", "Delete the selected page from this project");
			this.AddTooTip(cmdDeleteProp, "Delete Prop", "Delete the selected Prop object from this project. This will remove all references to this object.");
			this.AddTooTip(lvwEvar, "Evar List", "This is a list of all 'Evar' objects in this project.");
			this.AddTooTip(lvwEvent, "Event List", "This is a list of all 'Event' objects in this project.");
			this.AddTooTip(lvwProp, "Prop List", "This is a list of all 'Prop' objects in this project.");
			this.AddTooTip(lstEvarReference, "Associated Page Evar List", "This is a list of Evar objects associated with the above selected page.");
			this.AddTooTip(lstPropReference, "Associated Page Prop List", "This is a list of Prop objects associated with the above selected page.");
			this.AddTooTip(lstEventReference, "Associated Page Event List", "This is a list of Event objects associated with the above selected page.");
			//this.AddTooTip(tvwPage, "Site Page List", "This is a list of all site pages for this project.");
			this.AddTooTip(chkAllowErrorOnPageNotFound, "Page Load Error", "Determines if an error is generated for pages not defined in this project. When false, undefined pages will load with the globals settings.");
			this.AddTooTip(chkCustomSubmit, "Custom Submit", "Determines if the submit code is generated or custom. If true, you must build the submission routine manually.");
			this.AddTooTip(txtCustomSubmit, "Custom Submit", "Determines the script for a custom submit.");
			this.AddTooTip(chkTrackDownloadLinks, "Track Downloads", "Determines if download links are tracked.");
			this.AddTooTip(chkTrackExternalLinks, "Track External Links", "Determines if external link navigation is tracked.");
			this.AddTooTip(txtTrackExternalLinks, "Track Internal Links Types", "Determines the links considered to be internal. All other links are external.");
			this.AddTooTip(txtTrackDownloadLinks, "Track Download File Types", "Determines the file types considered for downloads.");

		}

		private void Parent_KeyDown(object sender, KeyEventArgs e)
		{
			if (lvwPage.SelectedItems.Count > 0)
			{
				if (e.KeyCode == Keys.Delete)
				{
					if (MessageBox.Show("Do you wish to delete the selected item(s)?", "Delete?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
					{
						List<ListViewItem> list = new List<ListViewItem>();
						list.AddRange(lvwPage.SelectedItems.ToArray());
						foreach (ListViewItemPageItem item in list)
						{
							if (item.PageItem != null)
							{
								_project.PageList.Remove(item.PageItem);
								_parentMDIForm.ObjectsWindow.UpdateDisplay();
								this.IsDirty = true;
							}
						}
						this.ReloadPages();
					}
				}
			}
		}

		//private void tvwPage_MouseUp(object sender, MouseEventArgs e)
		//{
		//  TreeViewHitTestInfo info =  tvwPage.HitTest(e.X, e.Y);
		//  if (info.Node != tvwPage.SelectedNode)
		//  {
		//    tvwPage.SelectedNode = info.Node;
		//  }
		//}

		private void ProjectForm_DockStateChanged(object sender, System.EventArgs e)
		{

		}

		public ProjectForm(MDIForm parentMDIForm, OmnitureProject project, Options options)
			: this()
		{
			_project = project;
			_options = options;
			_parentMDIForm = parentMDIForm;

			//Load Project
			_isLoading = true;
			txtProjectName.Text = this.Project.ProjectName;
			txtConfigFileFolder.Text = this.Project.ConfigFilePath;
			txtLibraryFolder.Text = this.Project.LibraryFilePath;
			txtScriptFile.Text = this.Project.ScriptFilePath;
			txtCompanyName.Text = this.Project.CompanyName;
			txtGlobalScriptVar.Text = this.Project.GlobalVariableName;
			chkAllowErrorOnPageNotFound.Checked = this.Project.AllowErrorOnPageNotFound;
			chkAllowPageRearrange.Checked = this.Project.AllowPageRearrange;
			chkCustomSubmit.Checked = this.Project.CustomSubmit;
			txtCustomSubmit.Text = this.Project.CustomSubmitScript;
			chkTrackExternalLinks.Checked = this.Project.TrackExternalLinks;
			chkTrackDownloadLinks.Checked = this.Project.TrackDownloadLinks;
			txtTrackExternalLinks.Text = this.Project.LinkInternalFilters;
			txtTrackDownloadLinks.Text = this.Project.LinkDownloadFileTypes;
			chkDebug.Checked = this.Project.IsDebug;

			_isLoading = false;
			this.Refresh();

		}

		#endregion

		#region Property Implementations

		public bool IsUILocked
		{
			get { return (_uiLockedCount != 0); }
		}

		public OmnitureProject Project
		{
			get { return _project; }
		}

		public bool IsDirty
		{
			get { return _isDirty; }
			set
			{
				_isDirty = value;
				this.UpdateCaption();
			}
		}

		public PropertyGrid PropertiesForm
		{
			get { return _propertyGrid; }
			set
			{
				_propertyGrid = value;

				if (lvwEvar.SelectedItems.Count > 0) this.UpdateTrackItem((ListViewItemITrack)lvwEvar.SelectedItems[0]);
				if (lvwProp.SelectedItems.Count > 0) this.UpdateTrackItem((ListViewItemITrack)lvwProp.SelectedItems[0]);
				if (lvwEvent.SelectedItems.Count > 0) this.UpdateTrackItem((ListViewItemITrack)lvwEvent.SelectedItems[0]);
				lvwEvar.Refresh();
				lvwEvent.Refresh();
				lvwProp.Refresh();

				if (lstEvarReference.SelectedIndex != -1) lstEvarReference.Items[lstEvarReference.SelectedIndex] = lstEvarReference.Items[lstEvarReference.SelectedIndex];
				if (lstEventReference.SelectedIndex != -1) lstEventReference.Items[lstEventReference.SelectedIndex] = lstEventReference.Items[lstEventReference.SelectedIndex];
				if (lstPropReference.SelectedIndex != -1) lstPropReference.Items[lstPropReference.SelectedIndex] = lstPropReference.Items[lstPropReference.SelectedIndex];
				lstEvarReference.Refresh();
				lstEventReference.Refresh();
				lstPropReference.Refresh();

				this.UpdateCaption();
				_parentMDIForm.ObjectsWindow.UpdateDisplay();

			}
		}

		public bool PageConfigurationShowing
		{
			get { return (this.wizard1.SelectedPage == pagePages); }
		}

		#endregion

		#region Methods

		private int _uiLockedCount = 0;

		/// <summary>
		/// Locks the UI from user input
		/// </summary>
		/// <remarks>This method should be called before the <seealso cref="UnlockUI"/> method</remarks>
		public void LockUI()
		{
			_uiLockedCount++;
			this.wizard1.Enabled = (_uiLockedCount == 0);
		}

		/// <summary>
		/// Attempts to unlock the UI
		/// </summary>
		/// <remarks>This method should be called after the <seealso cref="LockUI"/> method</remarks>
		public void UnlockUI()
		{
			_uiLockedCount--;
			this.wizard1.Enabled = (_uiLockedCount == 0);
		}

		/// <summary>
		/// Save the active project
		/// </summary>
		public void Save()
		{
			this.Project.Save(this.Project.FileName);
			this.IsDirty = false;
		}

		/// <summary>
		/// Updates the window text based on the project state
		/// </summary>
		private void UpdateCaption()
		{
			if (this.Project != null)
			{
				this.Text = this.Project.ProjectName + (this.IsDirty ? "*" : "");
			}
		}

		/// <summary>
		/// Builds the summary screen for the project wizard
		/// </summary>
		private void BuildSummary()
		{
			var sb = new StringBuilder();
			sb.AppendLine("Project: " + this.Project.ProjectName);
			sb.AppendLine("Document Key: " + this.Project.DocumentKey);
			sb.AppendLine("CompanyName: " + this.Project.CompanyName);
			sb.AppendLine("ConfigFilePath :" + this.Project.ConfigFilePath);
			sb.AppendLine("LibraryFilePath :" + this.Project.LibraryFilePath);
			sb.AppendLine("RevisionNumber :" + this.Project.RevisionNumber);
			sb.AppendLine("ScriptFilePath :" + this.Project.ScriptFilePath);

			//Evar list
			sb.AppendLine();
			sb.AppendLine("Evar List (" + this.Project.EVarList.Count + ")");
			foreach (EVarItem item in this.Project.EVarList)
			{
				sb.Append("\t" + item.Name + ", Alias: " + item.Alias);
				if (item.IsRequired) sb.AppendFormat(" (Required)");
				sb.AppendLine();
			}

			//Prop list
			sb.AppendLine();
			sb.AppendLine("Prop List (" + this.Project.PropList.Count + ")");
			foreach (PropItem item in this.Project.PropList)
			{
				sb.Append("\t" + item.Name + ", Alias: " + item.Alias);
				if (item.IsRequired) sb.AppendFormat(" (Required)");
				sb.AppendLine();
			}

			//Event list
			sb.AppendLine();
			sb.AppendLine("Event List (" + this.Project.EVarList.Count + ")");
			foreach (EventItem item in this.Project.EventList)
			{
				sb.AppendLine("\t" + item.Name + ", Alias: " + item.Alias);
			}

			//Pages
			sb.AppendLine();
			sb.AppendLine("Page List (" + this.Project.PageList.Count + ")");
			foreach (PageItem page in this.Project.PageList)
			{
				sb.AppendLine("\tChannel Name: " + page.ChannelName);
				sb.AppendLine("\tPage Name: " + page.PageName);
				sb.AppendLine("\tURL: " + page.PageURL);
				foreach (TrackReference reference in page.EVarList)
				{
					sb.AppendLine("\t\tEvar: " + reference.TrackItem.Name);
				}
				foreach (TrackReference reference in page.PropList)
				{
					sb.AppendLine("\t\tProp: " + reference.TrackItem.Name);
				}
				foreach (TrackReference reference in page.EventList)
				{
					sb.AppendLine("\t\tEvent: " + reference.TrackItem.Name);
				}
				sb.AppendLine();

			}

			txtSummary.Text = sb.ToString();
		}

		private void RefreshCurrentPageItem()
		{
			PageItem pageItem = null;
			if (lvwPage.SelectedItems.Count == 1) pageItem = ((ListViewItemPageItem)lvwPage.SelectedItems[0]).PageItem;
			if (pageItem == null) return;
			this.PropertiesForm.SelectedObject = pageItem;
			lstEvarReference.Items.Clear();
			lstEventReference.Items.Clear();
			lstPropReference.Items.Clear();

			if (pageItem != null)
			{
				lstEvarReference.Items.AddRange(pageItem.EVarList.ToArray());
				lstPropReference.Items.AddRange(pageItem.PropList.ToArray());
				lstEventReference.Items.AddRange(pageItem.EventList.ToArray());
			}
		}

		/// <summary>
		/// Build the project's binary
		/// </summary>
		/// <returns></returns>
		public bool BuildProject()
		{
			try
			{
				this.LockUI();
				if (this.ProcessErrors()) return false;
				this.PublishXML(true);

				//Now generate the library
				return this.Project.GenerateAssembly();

			}
			catch (Widgetsphere.GeneratorEngine.CompileException ex)
			{
				MessageBox.Show("The build failed.\n" + ex.Message, "Compile Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			catch (Exception ex)
			{
				throw;
			}
			finally
			{
				this.UnlockUI();
			}

		}

		/// <summary>
		/// Builds the project's XML
		/// </summary>
		public void PublishXML()
		{
			this.PublishXML(false);
		}

		/// <summary>
		/// Builds the project's XML
		/// </summary>
		/// <param name="silent">Determines if there is any user interaction</param>
		public void PublishXML(bool silent)
		{
			try
			{
				this.LockUI();
				if (!silent)
				{
					if (this.ProcessErrors()) return;
				}

				this.Project.GenerateXMLFile();

			}
			catch (Exception ex)
			{
				throw;
			}
			finally
			{
				this.UnlockUI();
			}

		}

		public void UpdateDisplay()
		{
			Control control = this.ActiveControl;
			this.RefreshListBox(lstEvarReference);
			this.RefreshListBox(lstPropReference);
			this.RefreshListBox(lstEventReference);
			this.RefreshTrackItemListView(lvwEvar);
			this.RefreshTrackItemListView(lvwProp);
			this.RefreshTrackItemListView(lvwEvent);
			this.RefreshPageListView(lvwPage);
			this.ActiveControl = control;
			this.BuildSummary();
		}

		/// <summary>
		/// Prompt the user for error and warnings
		/// </summary>
		/// <returns>True if the user cancelled the process</returns>
		private bool ProcessErrors()
		{
			//Errors
			ReadOnlyCollection<string> errorList = this.Project.GetErrorList();
			_parentMDIForm.MessageWindow.ErrorControl.ClearMessages();
			foreach (string s in errorList)
			{
				_parentMDIForm.MessageWindow.ErrorControl.AddMessage(new Omniture.Studio.Objects.Message(MessageTypeConstants.Error, s));
			}

			//Warnings
			ReadOnlyCollection<string> warningList = this.Project.GetWarningList();
			foreach (string s in warningList)
			{
				_parentMDIForm.MessageWindow.ErrorControl.AddMessage(new Omniture.Studio.Objects.Message(MessageTypeConstants.Warning, s));
			}

			if (errorList.Count > 0)
			{
				MessageBox.Show("There were errors. Please check the messages window.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return true;
			}
			else if (warningList.Count > 0)
			{
				if (MessageBox.Show("There were warnings. Please check the messages window. Do you wish to proceed?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
				{
					return true;
				}
			}

			return false;
		}

		public void ReloadPages()
		{
			try
			{
				if (this.PropertiesForm != null) this.PropertiesForm.SelectedObject = null;

				List<string> selectedPathList = new List<string>();
				foreach (ListViewItemPageItem item in lvwPage.SelectedItems)
				{
					selectedPathList.Add(item.PageItem.PageURL);
				}

				lvwPage.Items.Clear();

				//Add a random value in case there are duplicates
				Random rnd = new Random();
				SortedDictionary<string, PageItem> sortedList = new SortedDictionary<string, PageItem>();
				foreach (PageItem item in this.Project.PageList)
				{
					sortedList.Add(item.PageURL.ToLower() + rnd.Next(10000, 99999).ToString(), item);
				}

				foreach (string key in sortedList.Keys)
				{
					this.AddPageItem(sortedList[key]);
				}

				foreach (ListViewItemPageItem item in lvwPage.Items)
				{
					if (selectedPathList.Contains(item.PageItem.PageURL))
						item.Selected = true;
				}
			}
			catch (Exception ex)
			{
				throw;
			}

		}

		private ListViewItemPageItem AddPageItem(PageItem page)
		{
			string[] arr = page.PageURL.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
			if (arr.Length > 0)
			{
				var newItem = new ListViewItemPageItem(arr[arr.Length - 1]);
				newItem.SubItems.Add(string.Join("/", arr, 0, arr.Length - 1));
				newItem.SubItems.Add(page.ChannelName);
				newItem.PageItem = page;
				lvwPage.Items.Add(newItem);
				return newItem;
			}
			return null;
		}

		private void RefreshPageListView(ListView listView)
		{
			foreach (ListViewItemPageItem li in listView.Items)
			{
				this.UpdatePage(li);
			}
		}

		private void RefreshTrackItemListView(ListView listView)
		{
			foreach (ListViewItemITrack li in listView.Items)
			{
				this.UpdateTrackItem(li);
			}
		}

		private void RefreshListBox(ListBox listBox)
		{
			int selIndex = listBox.SelectedIndex;
			List<object> objectList = new List<object>();
			foreach (object o in listBox.Items)
			{
				objectList.Add(o);
			}
			listBox.Items.Clear();
			listBox.Items.AddRange(objectList.ToArray());
			listBox.SelectedIndex = selIndex;
		}

		private void AddTrackListItem(ITrackItem item)
		{
			ListView listView = null;
			if (item is EVarItem) listView = lvwEvar;
			else if (item is PropItem) listView = lvwProp;
			else if (item is EventItem) listView = lvwEvent;

			//Add the new item and scroll to see
			foreach (ListViewItemITrack x in listView.Items) x.Selected = false;
			ListViewItemITrack li = new ListViewItemITrack();
			li.TrackItem = item;
			li.Selected = true;
			this.UpdateTrackItem(li);
			listView.Items.Add(li);
			li.EnsureVisible();
		}

		private void UpdateTrackItem(ListViewItemITrack item)
		{
			ITrackItem trackItem = item.TrackItem;
			item.SubItems[0].Text = trackItem.Name;

			if (item.SubItems.Count > 1)
				item.SubItems[1].Text = trackItem.Alias;
			else
				item.SubItems.Add(trackItem.Alias);

			if (trackItem is EVarItem)
			{
				if (item.SubItems.Count > 2)
					item.SubItems[2].Text = ((EVarItem)trackItem).IsRequired.ToString();
				else
					item.SubItems.Add(((EVarItem)trackItem).IsRequired.ToString());

				if (item.SubItems.Count > 3)
					item.SubItems[3].Text = ((EVarItem)trackItem).DefaultValue;
				else
					item.SubItems.Add(((EVarItem)trackItem).DefaultValue);
			}
			if (trackItem is PropItem)
			{
				if (item.SubItems.Count > 2)
					item.SubItems[2].Text = ((PropItem)trackItem).IsRequired.ToString();
				else
					item.SubItems.Add(((PropItem)trackItem).IsRequired.ToString());

				if (item.SubItems.Count > 3)
					item.SubItems[3].Text = ((PropItem)trackItem).DefaultValue;
				else
					item.SubItems.Add(((PropItem)trackItem).DefaultValue);
			}

		}

		private void UpdatePage(ListViewItemPageItem item)
		{
			while (item.SubItems.Count < 3) item.SubItems.Add(string.Empty);

			item.SubItems[0].Text = item.PageItem.PageName;
			item.SubItems[1].Text = item.PageItem.PageURL;
			item.SubItems[2].Text = item.PageItem.ChannelName;
		}

		private void AddTooTip(Control ctrl, string header, string text)
		{
			helpProvider1.SetHelpString(ctrl, header + "\n\n" + text);
			toolTip1.SetToolTip(ctrl, header + "\n\n" + text);
		}

		private string GetProperCase(string text)
		{
			CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
			TextInfo textInfo = cultureInfo.TextInfo;
			return textInfo.ToTitleCase(text);
		}

		#endregion

		#region Event Handlers

		private void ProjectForm_Activated(object sender, System.EventArgs e)
		{
			if (_parentMDIForm != null) ((MDIForm)_parentMDIForm).CurrentWizard = this;
			this.PropertiesForm.SelectedObject = null;
			this.Refresh();
		}

		private void ProjectForm_FormClosed(object sender, FormClosedEventArgs e)
		{
			if (this.PropertiesForm != null)
				this.PropertiesForm.SelectedObject = null;
			//this.PropertiesForm.Close();
		}

		private void ProjectForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (this.IsUILocked)
			{
				e.Cancel = this.IsUILocked;
				return;
			}

			//Prompt is dirty
			if (this.IsDirty)
			{
				DialogResult dr = MessageBox.Show("Do you wish to save the '" + this.Project.ProjectName + "' project?", "Save '" + this.Project.ProjectName + "'?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
				if (dr == DialogResult.Yes)
				{
					e.Cancel = !((MDIForm)this.ParentForm).Save();
				}
				else if (dr == DialogResult.No)
				{
					//Do Nothing
				}
				else if (dr == DialogResult.Cancel)
				{
					e.Cancel = true;
				}
			}

			if (!e.Cancel)
			{
				((MDIForm)this.ParentForm).CurrentWizard = null;
				((MDIForm)this.ParentForm).ObjectsWindow.Project = null;
			}

		}

		private void txtProjectName_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.ProjectName = txtProjectName.Text;
				this.UpdateCaption();
				this.IsDirty = true;
			}
		}

		private void txtCompanyName_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.CompanyName = txtCompanyName.Text;
				this.IsDirty = true;
			}
		}

		private void txtCustomSubmit_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.CustomSubmitScript = txtCustomSubmit.Text;
				this.IsDirty = true;
			}
		}

		private void txtGlobalScriptVar_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.GlobalVariableName = txtGlobalScriptVar.Text;
				this.IsDirty = true;
			}
		}

		private void chkAllowErrorOnPageNotFound_CheckStateChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.AllowErrorOnPageNotFound = chkAllowErrorOnPageNotFound.Checked;
				this.IsDirty = true;
			}
		}

		private void chkAllowErrorOnPageNotFound_CheckedChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.AllowErrorOnPageNotFound = chkAllowErrorOnPageNotFound.Checked;
				this.IsDirty = true;
			}
		}

		private void chkAllowPageRearrange_CheckedChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.AllowPageRearrange = chkAllowPageRearrange.Checked;
				this.IsDirty = true;
			}
		}

		private void chkCustomSubmit_CheckedChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.CustomSubmit = chkCustomSubmit.Checked;
				this.IsDirty = true;
			}
			lblCustomSubmit.Enabled = chkCustomSubmit.Checked;
			txtCustomSubmit.Enabled = chkCustomSubmit.Checked;
		}

		private void txtTrackExternalLinks_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.LinkInternalFilters = txtTrackExternalLinks.Text;
				this.IsDirty = true;
			}
		}

		private void chkDebug_CheckedChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.IsDebug = chkDebug.Checked;
				this.IsDirty = true;
			}
		}

		private void txtTrackDownloadLinks_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.LinkDownloadFileTypes = txtTrackDownloadLinks.Text;
				this.IsDirty = true;
			}
		}

		private void txtScriptFile_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.ScriptFilePath = txtScriptFile.Text;
				this.IsDirty = true;
			}
		}

		private void txtLibraryFolder_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.LibraryFilePath = txtLibraryFolder.Text;
				this.IsDirty = true;
			}
		}

		private void txtConfigFileFolder_TextChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.ConfigFilePath = txtConfigFileFolder.Text;
				this.IsDirty = true;
			}
		}

		private void cmdAddEvar_Click(object sender, System.EventArgs e)
		{
			ITrackItem item = this.Project.EVarList.NewItem();
			this.AddTrackListItem(item);
			_parentMDIForm.ObjectsWindow.UpdateDisplay();
			this.IsDirty = true;
		}

		private void cmdDeleteEvar_Click(object sender, System.EventArgs e)
		{
			if (lvwEvar.SelectedItems.Count > 0)
			{
				int lastSelectIndex = -1;
				if (lvwEvar.SelectedItems.Count > 0)
					lastSelectIndex = lvwEvar.Items.IndexOf(lvwEvar.SelectedItems[0]);

				List<ListViewItem> delList = new List<ListViewItem>();
				foreach (ListViewItem lvi in lvwEvar.SelectedItems)
				{
					delList.Add(lvi);
					ITrackItem item = this.Project.EVarList[lvi.Text];
					this.Project.PageList.Clean(item);
				}

				foreach (ListViewItem item in delList)
				{
					this.Project.EVarList.Remove(item.Text);
					lvwEvar.Items.Remove(item);
				}

				if (lastSelectIndex > lvwEvar.Items.Count - 1) lastSelectIndex = lvwEvar.Items.Count - 1;
				if (lastSelectIndex != -1 && lastSelectIndex < lvwEvar.Items.Count) lvwEvar.Items[lastSelectIndex].Selected = true;

				_parentMDIForm.ObjectsWindow.UpdateDisplay();
				this.RefreshCurrentPageItem();
				this.IsDirty = true;
			}
		}

		private void cmdPasteEvar_Click(object sender, System.EventArgs e)
		{
			string text = Clipboard.GetText();
			text = text.Replace("\r", "");
			string[] lines = text.Split('\n');
			foreach (string line in lines)
			{
				string[] cols = line.Split('\t');
				if ((cols.Length > 0) && TrackItemBase.ValidateName(cols[0]))
				{
					ITrackItem item = this.Project.EVarList.NewItem();
					item.Name = cols[0];
					if (cols.Length > 1)
					{
						item.Alias = TrackItemBase.CreateToken(GetProperCase(cols[1]));
						item.Description = cols[1];
					}
					this.AddTrackListItem(item);
					_parentMDIForm.ObjectsWindow.UpdateDisplay();
					this.IsDirty = true;
				}
				else if (cols[0] != "")
				{
					MessageBox.Show("The name '" + cols[0] + "' is not valid. This item was skipped.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		private void cmdAddProp_Click(object sender, System.EventArgs e)
		{
			ITrackItem item = this.Project.PropList.NewItem();
			this.AddTrackListItem(item);
			_parentMDIForm.ObjectsWindow.UpdateDisplay();
			this.IsDirty = true;
		}

		private void cmdDeleteProp_Click(object sender, System.EventArgs e)
		{
			if (lvwProp.SelectedItems.Count > 0)
			{
				int lastSelectIndex = -1;
				if (lvwProp.SelectedItems.Count > 0)
					lastSelectIndex = lvwProp.Items.IndexOf(lvwProp.SelectedItems[0]);

				List<ListViewItem> delList = new List<ListViewItem>();
				foreach (ListViewItem lvi in lvwProp.SelectedItems)
				{
					delList.Add(lvi);
					ITrackItem item = this.Project.PropList[lvi.Text];
					this.Project.PageList.Clean(item);
				}

				foreach (ListViewItem item in delList)
				{
					this.Project.PropList.Remove(item.Text);
					lvwProp.Items.Remove(item);
				}

				if (lastSelectIndex > lvwProp.Items.Count - 1) lastSelectIndex = lvwProp.Items.Count - 1;
				if (lastSelectIndex != -1 && lastSelectIndex < lvwProp.Items.Count) lvwProp.Items[lastSelectIndex].Selected = true;

				_parentMDIForm.ObjectsWindow.UpdateDisplay();
				this.RefreshCurrentPageItem();
				this.IsDirty = true;
			}
		}

		private void cmdPasteProp_Click(object sender, System.EventArgs e)
		{
			string text = Clipboard.GetText();
			text = text.Replace("\r", "");
			string[] lines = text.Split('\n');
			foreach (string line in lines)
			{
				string[] cols = line.Split('\t');
				if ((cols.Length > 0) && TrackItemBase.ValidateName(cols[0]))
				{
					ITrackItem item = this.Project.PropList.NewItem();
					item.Name = cols[0];
					if (cols.Length > 1)
					{
						item.Alias = TrackItemBase.CreateToken(GetProperCase(cols[1]));
						item.Description = cols[1];
					}
					this.AddTrackListItem(item);
					_parentMDIForm.ObjectsWindow.UpdateDisplay();
					this.IsDirty = true;
				}
				else if (cols[0] != "")
				{
					MessageBox.Show("The name '" + cols[0] + "' is not valid. This item was skipped.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		private void cmdAddEvent_Click(object sender, System.EventArgs e)
		{
			ITrackItem item = this.Project.EventList.NewItem();
			this.AddTrackListItem(item);
			_parentMDIForm.ObjectsWindow.UpdateDisplay();
			this.IsDirty = true;
		}

		private void cmdDeleteEvent_Click(object sender, System.EventArgs e)
		{
			if (lvwEvent.SelectedItems.Count > 0)
			{
				int lastSelectIndex = -1;
				if (lvwEvent.SelectedItems.Count > 0)
					lastSelectIndex = lvwEvent.Items.IndexOf(lvwEvent.SelectedItems[0]);

				List<ListViewItem> delList = new List<ListViewItem>();
				foreach (ListViewItem lvi in lvwEvent.SelectedItems)
				{
					delList.Add(lvi);
					ITrackItem item = this.Project.EventList[lvi.Text];
					this.Project.PageList.Clean(item);
				}

				foreach (ListViewItem item in delList)
				{
					this.Project.EventList.Remove(item.Text);
					lvwEvent.Items.Remove(item);
				}

				if (lastSelectIndex > lvwEvent.Items.Count - 1) lastSelectIndex = lvwEvent.Items.Count - 1;
				if (lastSelectIndex != -1 && lastSelectIndex < lvwEvent.Items.Count) lvwEvent.Items[lastSelectIndex].Selected = true;

				_parentMDIForm.ObjectsWindow.UpdateDisplay();
				this.RefreshCurrentPageItem();
				this.IsDirty = true;
			}
		}

		private void cmdPasteEvent_Click(object sender, System.EventArgs e)
		{
			string text = Clipboard.GetText();
			text = text.Replace("\r", "");
			string[] lines = text.Split('\n');
			foreach (string line in lines)
			{
				string[] cols = line.Split('\t');
				if ((cols.Length > 0) && TrackItemBase.ValidateName(cols[0]))
				{
					ITrackItem item = this.Project.EventList.NewItem();
					item.Name = cols[0];
					if (cols.Length > 1)
					{
						item.Alias = TrackItemBase.CreateToken(GetProperCase(cols[1]));
						item.Description = cols[1];
					}
					this.AddTrackListItem(item);
					_parentMDIForm.ObjectsWindow.UpdateDisplay();
					this.IsDirty = true;
				}
				else if (cols[0] != "")
				{
					MessageBox.Show("The name '" + cols[0] + "' is not valid. This item was skipped.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		private void cmdAddPage_Click(object sender, System.EventArgs e)
		{
			PageItem item = this.Project.PageList.NewItem();
			item.PageURL = "[NewPage]";
			lvwPage.UnSelectAll();
			ListViewItemPageItem lvw = this.AddPageItem(item);
			lvw.Selected = true;
			lvw.EnsureVisible();
			this.IsDirty = true;
		}

		private void cmdDeletePage_Click(object sender, System.EventArgs e)
		{
			List<ListViewItem> list = new List<ListViewItem>();
			list.AddRange(lvwPage.SelectedItems.ToArray());
			if (list.Count > 0)
			{
				if (MessageBox.Show("Do you wish to delete these " + list.Count + " page(s)", "Delete?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
				{
					foreach (ListViewItemPageItem item in list)
					{
						if (item.PageItem != null)
						{
							this.Project.PageList.Remove(item.PageItem);
							this.IsDirty = true;
						}
					}
					this.ReloadPages();
				}
			}
		}

		private void lvwEvar_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			ListView lv = (ListView)sender;
			if (lv.SelectedItems.Count != 1)
			{
				this.PropertiesForm.SelectedObject = null;
			}
			else
			{
				ITrackItem item = ((ListViewItemITrack)lv.SelectedItems[0]).TrackItem;
				this.PropertiesForm.SelectedObject = item;
			}
		}

		private void lvwProp_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			ListView lv = (ListView)sender;
			if (lv.SelectedItems.Count != 1)
			{
				this.PropertiesForm.SelectedObject = null;
			}
			else
			{
				ITrackItem item = ((ListViewItemITrack)lv.SelectedItems[0]).TrackItem;
				this.PropertiesForm.SelectedObject = item;
			}
		}

		private void lvwEvent_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			ListView lv = (ListView)sender;
			if (lv.SelectedItems.Count != 1)
			{
				this.PropertiesForm.SelectedObject = null;
			}
			else
			{
				ITrackItem item = ((ListViewItemITrack)lv.SelectedItems[0]).TrackItem;
				this.PropertiesForm.SelectedObject = item;
			}
		}

		private void ReferenceListBox_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			TrackReference item = ((TrackReference)((ListBox)sender).SelectedItem);
			if (item == null)
				this.PropertiesForm.SelectedObject = null;
			else
				this.PropertiesForm.SelectedObject = item.TrackItem;
		}

		private void lvwPage_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
		{
			this.PropertiesForm.SelectedObject = null;
			if (lvwPage.SelectedItems.Count == 1)
			{
				PageItem item = ((ListViewItemPageItem)lvwPage.SelectedItems[0]).PageItem;
				if (item != null) this.PropertiesForm.SelectedObject = item;
			}
			this.RefreshCurrentPageItem();
		}

		private void wizard1_AfterSwitchPages(object sender, Gravitybox.Controls.Wizard.Wizard.AfterSwitchPagesEventArgs e)
		{
			_parentMDIForm.ObjectsWindow.AllowDisplay = this.PageConfigurationShowing;
			_parentMDIForm.ObjectsWindow.UpdateDisplay();
		}

		private void wizard1_BeforeSwitchPages(object sender, Gravitybox.Controls.Wizard.Wizard.BeforeSwitchPagesEventArgs e)
		{
			if (e.NewIndex == wizard1.WizardPages.Count - 1)
			{
				this.BuildSummary();
			}

			this.PropertiesForm.SelectedObject = null;
		}

		private void lstEvarReference_DragDrop(object sender, DragEventArgs e)
		{
			EVarItem item = (EVarItem)e.Data.GetData(typeof(EVarItem));
			if ((item != null) && (lvwPage.SelectedItems.Count == 1))
			{
				PageItem page = ((ListViewItemPageItem)lvwPage.SelectedItems[0]).PageItem;
				if ((page != null) && (page.EVarList.FindByObject(item) == null))
				{
					TrackReference newRef = page.EVarList.NewItem(item);
					lstEvarReference.Items.Add(newRef);
					this.IsDirty = true;
				}
				else
				{
					MessageBox.Show("This specified object is already in the destination list.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		//private void tvwPage_DragDrop(object sender, DragEventArgs e)
		//{

		//}

		//private void tvwPage_DragEnter(object sender, DragEventArgs e)
		//{

		//}

		private void lstEvarReference_DragEnter(object sender, DragEventArgs e)
		{
			if (e.Data.GetData(typeof(EVarItem)) != null)
				e.Effect = DragDropEffects.Copy;
		}

		private void lstPropReference_DragDrop(object sender, DragEventArgs e)
		{
			PropItem item = (PropItem)e.Data.GetData(typeof(PropItem));
			if ((item != null) && (lvwPage.SelectedItems.Count == 1))
			{
				PageItem page = ((ListViewItemPageItem)lvwPage.SelectedItems[0]).PageItem;
				if ((page != null) && (page.PropList.FindByObject(item) == null))
				{
					TrackReference newRef = page.PropList.NewItem(item);
					lstPropReference.Items.Add(newRef);
					this.IsDirty = true;
				}
				else
				{
					MessageBox.Show("This specified object is already in the destination list.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		private void lstPropReference_DragEnter(object sender, DragEventArgs e)
		{
			if (e.Data.GetData(typeof(PropItem)) != null)
				e.Effect = DragDropEffects.Copy;
		}

		private void lstEventReference_DragDrop(object sender, DragEventArgs e)
		{
			EventItem item = (EventItem)e.Data.GetData(typeof(EventItem));
			if ((item != null) && (lvwPage.SelectedItems.Count == 1))
			{
				PageItem page = ((ListViewItemPageItem)lvwPage.SelectedItems[0]).PageItem;
				if ((page != null) && (page.EventList.FindByObject(item) == null))
				{
					TrackReference newRef = page.EventList.NewItem(item);
					lstEventReference.Items.Add(newRef);
					this.IsDirty = true;
				}
				else
				{
					MessageBox.Show("This specified object is already in the destination list.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		private void lstEventReference_DragEnter(object sender, DragEventArgs e)
		{
			if (e.Data.GetData(typeof(EventItem)) != null)
				e.Effect = DragDropEffects.Copy;
		}

		private void cmdConfigFileFolder_Click(object sender, System.EventArgs e)
		{
			FolderBrowserDialog d = new FolderBrowserDialog();
			d.Description = "Select the folder that stores the generated configuration file.";
			if (d.ShowDialog() == DialogResult.OK)
			{
				txtConfigFileFolder.Text = d.SelectedPath;
				this.IsDirty = true;
			}
		}

		private void cmdLibraryFolder_Click(object sender, System.EventArgs e)
		{
			FolderBrowserDialog d = new FolderBrowserDialog();
			d.Description = "Select the folder that stores the generated configuration library.";
			if (d.ShowDialog() == DialogResult.OK)
			{
				txtLibraryFolder.Text = d.SelectedPath;
				this.IsDirty = true;
			}
		}

		private void wizard1_Finish(object sender, System.EventArgs e)
		{
			if (this.BuildProject())
			{
				BuildSummaryForm F = new BuildSummaryForm();
				F.SummaryText = "Custom library compiled and copied it to the following location:\r\n" +
				Path.Combine(this.Project.LibraryFilePath, this.Project.LibraryName) + "\r\n\r\n" +
				"XML configuration file generated and copied to the following location:\r\n" +
				Path.Combine(this.Project.ConfigFilePath, this.Project.XMLConfigFileName);
				F.ShowDialog();
			}
		}

		private void lstEventReference_KeyDown(object sender, KeyEventArgs e)
		{
			if (lstEventReference.SelectedIndex != -1)
			{
				if (e.KeyCode == Keys.Delete)
				{
					if (MessageBox.Show("Do you wish to delete this item?", "Delete?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
					{
						List<ListViewItem> list = new List<ListViewItem>(lvwPage.SelectedItems.ToArray());
						foreach (ListViewItemPageItem item in list)
						{
							item.PageItem.EventList.RemoveAt(lstEventReference.SelectedIndex);
							lstEventReference.Items.RemoveAt(lstEventReference.SelectedIndex);
						}
						_parentMDIForm.ObjectsWindow.UpdateDisplay();
						this.IsDirty = true;
					}
				}
			}
		}

		private void lstPropReference_KeyDown(object sender, KeyEventArgs e)
		{
			if (lstPropReference.SelectedIndex != -1)
			{
				if (e.KeyCode == Keys.Delete)
				{
					if (MessageBox.Show("Do you wish to delete this item?", "Delete?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
					{
						List<ListViewItem> list = new List<ListViewItem>(lvwPage.SelectedItems.ToArray());
						foreach (ListViewItemPageItem item in list)
						{
							item.PageItem.PropList.RemoveAt(lstPropReference.SelectedIndex);
							lstPropReference.Items.RemoveAt(lstPropReference.SelectedIndex);
						}
						_parentMDIForm.ObjectsWindow.UpdateDisplay();
						this.IsDirty = true;
					}
				}
			}
		}

		private void lstEvarReference_KeyDown(object sender, KeyEventArgs e)
		{
			if (lstEvarReference.SelectedIndex != -1)
			{
				if (e.KeyCode == Keys.Delete)
				{
					if (MessageBox.Show("Do you wish to delete this item?", "Delete?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
					{
						List<ListViewItem> list = new List<ListViewItem>(lvwPage.SelectedItems.ToArray());
						foreach (ListViewItemPageItem item in list)
						{
							item.PageItem.EVarList.RemoveAt(lstEvarReference.SelectedIndex);
							lstEvarReference.Items.RemoveAt(lstEvarReference.SelectedIndex);
						}
						_parentMDIForm.ObjectsWindow.UpdateDisplay();
						this.IsDirty = true;
					}
				}
			}
		}

		private void chkTrackDownloadLinks_CheckedChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.TrackDownloadLinks = chkTrackDownloadLinks.Checked;
				this.IsDirty = true;
			}
			lblTrackDownloadLinks.Enabled = chkTrackDownloadLinks.Checked;
			txtTrackDownloadLinks.Enabled = chkTrackDownloadLinks.Checked;
		}

		private void chkTrackExternalLinks_CheckedChanged(object sender, System.EventArgs e)
		{
			if (!_isLoading)
			{
				this.Project.TrackExternalLinks = chkTrackExternalLinks.Checked;
				this.IsDirty = true;
			}
			lblTrackExternalLinks.Enabled = chkTrackExternalLinks.Checked;
			txtTrackExternalLinks.Enabled = chkTrackExternalLinks.Checked;
		}

		public override void Refresh()
		{
			base.Refresh();

			_isLoading = true;

			lvwEvar.Items.Clear();
			lvwProp.Items.Clear();
			lvwEvent.Items.Clear();

			foreach (ITrackItem item in this.Project.EVarList)
				this.AddTrackListItem(item);

			foreach (ITrackItem item in this.Project.EventList)
				this.AddTrackListItem(item);

			foreach (ITrackItem item in this.Project.PropList)
				this.AddTrackListItem(item);

			foreach (ListViewItem li in lvwEvar.Items) li.Selected = false;
			foreach (ListViewItem li in lvwProp.Items) li.Selected = false;
			foreach (ListViewItem li in lvwEvent.Items) li.Selected = false;

			if (lvwEvar.Items.Count > 0) lvwEvar.Items[0].EnsureVisible();
			if (lvwProp.Items.Count > 0) lvwProp.Items[0].EnsureVisible();
			if (lvwEvent.Items.Count > 0) lvwEvent.Items[0].EnsureVisible();

			this.ReloadPages();
			this.RefreshCurrentPageItem();

			_parentMDIForm.ObjectsWindow.AllowDisplay = this.PageConfigurationShowing;
			_parentMDIForm.ObjectsWindow.UpdateDisplay();

			_isLoading = false;

		}

		private void ProjectForm_KeyUp(object sender, KeyEventArgs e)
		{
			if (e.Control && e.KeyCode == Keys.S)
			{
				this.Save();
			}
		}

		#endregion

	}
}